package cn.qiyu5522.tk_ems.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.qiyu5522.tk_ems.entity.Classroom;
import cn.qiyu5522.tk_ems.entity.Department;
import cn.qiyu5522.tk_ems.entity.Major;
import cn.qiyu5522.tk_ems.entity.dto.QueryParamDTO;
import cn.qiyu5522.tk_ems.entity.vo.MajorVO;
import cn.qiyu5522.tk_ems.mapper.ClassroomMapper;
import cn.qiyu5522.tk_ems.mapper.DepartmentMapper;
import cn.qiyu5522.tk_ems.mapper.MajorMapper;
import cn.qiyu5522.tk_ems.result.CustomMapResult;
import cn.qiyu5522.tk_ems.result.R;
import cn.qiyu5522.tk_ems.retrofit.IdGeneratorApi;
import cn.qiyu5522.tk_ems.service.ClassroomService;
import cn.qiyu5522.tk_ems.service.DepartmentService;
import cn.qiyu5522.tk_ems.service.MajorService;
import cn.qiyu5522.tk_ems.utils.RedisKey;
import cn.qiyu5522.tk_ems.utils.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Tonkey
 * @since 2023-02-04
 */
@Slf4j
@Service
public class MajorServiceImpl extends ServiceImpl<MajorMapper, Major> implements MajorService {

    @Resource
    private IdGeneratorApi idGeneratorApi;
    @Resource
    private ClassroomMapper classroomMapper;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private ClassroomService classroomService;

    @Override
    public R queryMajorByPageCondition(QueryParamDTO<MajorVO> queryParamDTO) {
        MajorVO condition = queryParamDTO.getCondition();
        IPage<Major> majorIPage = new Page<Major>(queryParamDTO.getCurrentPage(), queryParamDTO.getPageSize());
        LambdaQueryWrapper<Major> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(ObjectUtil.isNotEmpty(condition.getName()), Major::getName, condition.getName())
        .eq(ObjectUtil.isNotEmpty(condition.getDepartmentId()),Major::getDepartmentId,condition.getDepartmentId());
        baseMapper.selectPage(majorIPage, lambdaQueryWrapper);
        // 从redis 中取出院系编号与名称
        List<Department> departments = departmentService.getForIdAndName();
        List<MajorVO> majorVOS = objectMapper.convertValue(majorIPage.getRecords(), new TypeReference<List<MajorVO>>() {
        });

        List<MajorVO> majorVOList = majorVOS.stream().map(major -> {
            departments.forEach(department -> {
                if (department.getId().equals(major.getDepartmentId())) {
                    major.setDepartment(department.getName());
                }
            });
            return major;
        }).collect(Collectors.toList());
        Map<String, Object> map = CustomMapResult.packagingResult(majorVOList, queryParamDTO.getCurrentPage(), queryParamDTO.getPageSize(), majorIPage.getTotal());
        return R.ok().data("majorIPage", map);
    }

    @Override
    public R saveMore(List<MajorVO> majorVOS) {
        // 待添加的专业信息集合
        List<Major> Majors = new ArrayList<>(majorVOS.size());
        Major major = null;
        for (MajorVO MajorVo : majorVOS) {
            // 对象转换将VO类型转为实体类型
            major = new Major();
            BeanUtils.copyProperties(MajorVo, major);
            // 调用远程接口 生成专业编号
            Long majorId = Long.valueOf(idGeneratorApi.getDefaultId(String.valueOf(major.getDepartmentId())));
            major.setId(majorId);
            Majors.add(major);
        }
        // 添加
        Integer integer = baseMapper.insertBatchSomeColumn(Majors);
        // 添加成功，刷新Redis中的缓存
        if(integer>0){
            // 查询全部的专业数据
            QueryWrapper<Major> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name","department_id");
            List<Major> majorList = baseMapper.selectList(queryWrapper);
            redisUtil.set(RedisKey.MAJOR_ID_AND_NAME,majorList,RedisKey.EXPIRE_ONE_DAY);
        }
        return integer.compareTo(0) > 0 ? R.ok().message("专业添加成功") : R.error().message("专业添加失败");
    }

    @Override
    public R removeMore(List<Long> ids) {
        LambdaQueryWrapper<Classroom> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(Classroom::getMajorId,ids);
        List<Classroom> classrooms = classroomMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(classrooms)) {
            return R.error().message("该专业下存在班级关联数据无法删除");
        }
        int i = baseMapper.deleteBatchIds(ids);
        // 删除成功，刷新Redis中的缓存
        if(i>0){
            // 查询全部的院系数据
            QueryWrapper<Major> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name","department_id");
            List<Major> majorList = baseMapper.selectList(queryWrapper);
            redisUtil.set(RedisKey.MAJOR_ID_AND_NAME,majorList,RedisKey.EXPIRE_ONE_DAY);
        }
        return i > 0 ? R.ok().message("专业删除成功") : R.error().message("专业删除失败");
    }




    @Override
    public List<Major> getForIdAndNameDepId() {
        List<Major> majors = new ArrayList<>();
        log.info("从Redis中拿取 专业编号与名称列表");
        majors = (List<Major>) redisUtil.get(RedisKey.MAJOR_ID_AND_NAME);
        if (CollectionUtil.isEmpty(majors)) {
            log.info("Redis中无 专业编号与名称列表 ");
            QueryWrapper<Major> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id", "name","department_id");
            majors = baseMapper.selectList(queryWrapper);
            if (majors.size() != 0) {
                log.info("将 专业编号与名称列表 存入redis");
                redisUtil.set(RedisKey.MAJOR_ID_AND_NAME, majors, RedisKey.EXPIRE_ONE_DAY);
            }
        }
        return majors;

    }

    @Override
    public R queryForIdAndNameByDepartmentId(Long id) {
        QueryWrapper<Major> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(id),"department_id",id);
        List<Major> majors = baseMapper.selectList(queryWrapper);
        // Major 转Vo
        List<cn.qiyu5522.tk_ems.entity.dto.MajorVO> majorVOS = objectMapper.convertValue(majors, new TypeReference<List<cn.qiyu5522.tk_ems.entity.dto.MajorVO>>() {
        });
        // 查询全部院系
//        List<Department> departments = departmentMapper.selectList(null);
        // 从 redis 中取
        List<Department> departments = (List<Department>) redisUtil.get(RedisKey.DEPARTMENT_ID_AND_NAME);
        List<cn.qiyu5522.tk_ems.entity.dto.MajorVO> majorVOList = majorVOS.stream().map(major -> {
            departments.forEach(department -> {
                if (department.getId().equals(major.getDepartmentId())) {
                    major.setDepartment(department.getName());
                }
            });
            return major;
        }).collect(Collectors.toList());
        return majorVOList.size() !=0? R.ok().data("majorsByDepId",majorVOList):R.ok().data("majorsByDepId",new ArrayList<>(0));
    }

    @Override
    public R queryByName(String name) {
        QueryWrapper<Major> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(name),"name",name);
        List<Major> majors = baseMapper.selectList(queryWrapper);
        return majors.size()==0?
                R.ok().message("名称可用").data("flag",true):
                R.ok().message("名称不可用").data("flag",false);
    }

}
